using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form;
using Volo.Abp.ObjectMapping;

namespace CKY.AgentPlatform.Web.Pages.Caching
{
    public class IndexModel : AgentPlatformPageModel
    {
        private readonly DistributedCacheService _cacheService;
        private readonly RedisCacheService _redisCacheService;
        private readonly CacheHealthCheck _cacheHealthCheck;
        private readonly IObjectMapper _objectMapper;
        private readonly ILogger<IndexModel> _logger;

        public IndexModel(
            DistributedCacheService cacheService,
            RedisCacheService redisCacheService,
            CacheHealthCheck cacheHealthCheck,
            IObjectMapper objectMapper,
            ILogger<IndexModel> logger)
        {
            _cacheService = cacheService;
            _redisCacheService = redisCacheService;
            _cacheHealthCheck = cacheHealthCheck;
            _objectMapper = objectMapper;
            _logger = logger;
        }

        [ViewData]
        public string PageTitle { get; set; }

        public CacheStatusDto CacheStatus { get; set; }
        public WebCacheStatisticsDto CacheStatistics { get; set; }
        public List<SlowQueryLogDto> SlowQueries { get; set; }
        public List<string> CacheKeys { get; set; }
        public CacheValueDto SelectedCacheValue { get; set; }

        public string SelectedKey { get; set; }
        public string SearchPattern { get; set; } = "*";
        public int SlowQueryCount { get; set; } = 100;

        public async Task OnGetAsync()
        {
            PageTitle = "缓存管理";
            
            await LoadCacheDataAsync();
        }

        public async Task<IActionResult> OnPostClearCacheAsync(string key = null, string pattern = null)
        {
            try
            {
                if (!string.IsNullOrEmpty(key))
                {
                    await _cacheService.RemoveAsync(key);
                    Notifications.Success($"缓存 '{key}' 已清除");
                }
                else if (!string.IsNullOrEmpty(pattern))
                {
                    if (_redisCacheService != null)
                    {
                        await _redisCacheService.ClearPatternAsync(pattern);
                        Notifications.Success($"模式 '{pattern}' 的缓存已清除");
                    }
                }
                else
                {
                    await _cacheService.ClearAllAsync();
                    Notifications.Success("所有缓存已清除");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清除缓存失败");
                Notifications.Error("清除缓存失败: " + ex.Message);
            }

            await LoadCacheDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostGetCacheValueAsync(string key)
        {
            SelectedKey = key;
            
            try
            {
                var value = await _cacheService.GetAsync<object>(key);
                var expiration = await _cacheService.GetExpirationAsync(key);
                
                SelectedCacheValue = new CacheValueDto
                {
                    Key = key,
                    Value = value,
                    Exists = value != null,
                    Expiration = expiration,
                    Timestamp = DateTime.UtcNow
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存值失败: {Key}", key);
                Notifications.Error("获取缓存值失败: " + ex.Message);
            }

            await LoadCacheDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostSearchKeysAsync()
        {
            await LoadCacheDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostRefreshConfigAsync()
        {
            try
            {
                var configService = ServiceProvider.GetService<CacheConfigurationService>();
                if (configService != null)
                {
                    await configService.ConfigureCacheAsync();
                    Notifications.Success("缓存配置刷新成功");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "刷新缓存配置失败");
                Notifications.Error("刷新缓存配置失败: " + ex.Message);
            }

            await LoadCacheDataAsync();
            return Page();
        }

        public async Task<IActionResult> OnPostWarmUpCacheAsync()
        {
            try
            {
                var configService = ServiceProvider.GetService<CacheConfigurationService>();
                if (configService != null)
                {
                    await configService.WarmUpCacheAsync();
                    Notifications.Success("缓存预热成功");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "缓存预热失败");
                Notifications.Error("缓存预热失败: " + ex.Message);
            }

            await LoadCacheDataAsync();
            return Page();
        }

        private async Task LoadCacheDataAsync()
        {
            try
            {
                // 加载缓存状态
                var status = await _cacheHealthCheck.CheckHealthAsync();
                CacheStatus = _objectMapper.Map<CacheHealthStatus, CacheStatusDto>(status);

                // 加载缓存统计信息
                CacheStatistics = new CacheStatisticsDto
                {
                    Timestamp = DateTime.UtcNow,
                    TotalOperations = await GetTotalOperationsAsync(),
                    CacheHitRate = await GetCacheHitRateAsync()
                };

                if (_redisCacheService != null)
                {
                    var redisStats = await _redisCacheService.GetStatisticsAsync();
                    CacheStatistics.RedisStatistics = _objectMapper.Map<RedisStatistics, RedisStatisticsDto>(redisStats);
                }

                // 加载慢查询日志
                if (_redisCacheService != null)
                {
                    var logs = await _redisCacheService.GetSlowQueryLogsAsync(SlowQueryCount);
                    SlowQueries = _objectMapper.Map<List<SlowQueryLog>, List<SlowQueryLogDto>>(logs);
                }

                // 加载缓存键
                if (_redisCacheService != null)
                {
                    CacheKeys = await _redisCacheService.GetKeysAsync(SearchPattern);
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "加载缓存数据失败");
                Notifications.Error("加载缓存数据失败: " + ex.Message);
            }
        }

        private async Task<long> GetTotalOperationsAsync()
        {
            return await _cacheService.GetLongAsync("statistics:operations:count");
        }

        private async Task<double> GetCacheHitRateAsync()
        {
            return await _cacheService.GetDoubleAsync("statistics:hit:rate");
        }
    }

    public class CacheStatusDto
    {
        public bool OverallHealth { get; set; }
        public bool DistributedCacheHealthy { get; set; }
        public bool? RedisHealthy { get; set; }
        public DateTime LastCheck { get; set; }
        public string ErrorMessage { get; set; }
    }

    public class WebCacheStatisticsDto
    {
        public DateTime Timestamp { get; set; }
        public long TotalOperations { get; set; }
        public double CacheHitRate { get; set; }
        public RedisStatisticsDto RedisStatistics { get; set; }
    }

    public class RedisStatisticsDto
    {
        public long UsedMemory { get; set; }
        public long MaxMemory { get; set; }
        public long KeyspaceHits { get; set; }
        public long KeyspaceMisses { get; set; }
        public long ConnectedClients { get; set; }
        public long TotalCommandsProcessed { get; set; }
        public long KeysCount { get; set; }
        public double CacheHitRate { get; set; }
        public double AverageResponseTime { get; set; }
        public double HitRatePercentage { get; set; }
        public string UsedMemoryFormatted { get; set; }
        public string MaxMemoryFormatted { get; set; }
    }

    public class SlowQueryLogDto
    {
        public DateTime Timestamp { get; set; }
        public string Operation { get; set; }
        public string Query { get; set; }
        public long ExecutionTime { get; set; }
        public string UserAgent { get; set; }
    }

    public class CacheValueDto
    {
        public string Key { get; set; }
        public object Value { get; set; }
        public bool Exists { get; set; }
        public DateTimeOffset? Expiration { get; set; }
        public DateTime Timestamp { get; set; }
    }
}